<template>
	<view>
		<u-navbar title="视频合成" titleStyle="color:#fff;" :placeholder="true" leftIconColor="#fff" :autoBack="true" bgColor="rgba(0,0,0,0)">
			
		</u-navbar>
		
		<view class="synth_video">
			<image class="ph" :src="videoImg" mode="heightFix"></image>
		</view>
		
		<view class="synth_drive">
			<view class="tabs_nav">
				<view class="item" :class="tabsIndex == 0?'hover':''" @click="clickTabs(0)">
					语音驱动
				</view>
				<view class="item" :class="tabsIndex == 1?'hover':''" @click="clickTabs(1)">
					文本驱动
				</view>
			</view>
			<view v-if="tabsIndex == 0" class="tabs_cont">
				
				<view v-if="isSoundPlay == 0">
					<view v-if="!isRecording" class="read_play">
						<view class="btn" @click="recorderStart">
							<u-icon name="mic" color="#F9BE01" size="100rpx"></u-icon>
						</view>
					</view>
					<view v-if="isRecording" class="read_end">
						<view class="name">
							录音中
						</view>
						<view class="text">
							你可以唱歌或者说话，别紧张，好好说！
						</view>
						<image class="ico" src="../static/img/ico_sound.png" mode="widthFix"></image>
						<view class="time">
							{{timerDisplay}}
						</view>
						<view class="btn" @click="recorderEnd">
							结束录音
						</view>
					</view>
				</view>
				
				<view v-if="isSoundPlay == 2" class="step3_btn">
					<view class="item">
						<view class="btn_reload" @click="reUpload">
							<view class="bgff">
								<u-icon name="reload" color="#494949" size="40rpx" bold></u-icon>
							</view>
						</view>
						<view class="name">
							重新上传
						</view>
					</view>
					<view class="item">
						<view class="btn_listen" v-if="!isAudioPaly" @click="clickOnPlayAudio">
							<u-icon name="play-right-fill" color="#292D32" size="50rpx"></u-icon>
						</view>
						<view class="btn_listen" v-if="isAudioPaly"  @click="clickOnStopAudio">
							<u-icon name="pause" color="#292D32" size="50rpx"></u-icon>
						</view>
						<view class="name">
							试听
						</view>
					</view>
				</view>
				
			</view>
			<view v-if="tabsIndex == 1" class="tabs_cont">
				<view class="textarea_sound">
					<textarea class="textarea" style="width: 100%;height: 76%;" v-model="textarea" maxlength="-1" :disable-default-padding="true" placeholder-style="color:#9B9B9B" placeholder="请输入文案"/>
					<view v-if="textarea" class="textarea_btn" @click="postSpeedAudioCreate">
						合成声音
					</view>
					<view v-else class="textarea_btn disabled">
						合成声音
					</view>
				</view>
				<view class="text_sound">
					<view class="title">
						数字声音
					</view>
					<view class="text">
						{{audioTitle}}
					</view>
				</view>
			</view>
		</view>
		
		<!-- <view v-if="isSoundPlay == 0 && tabsIndex == 0" class="wx_up" @click="getWeixinFile">
			<view class="name green">
				<text>从微信聊天上传</text>
				<u-icon name="arrow-right" color="#00E16F" size="28rpx"></u-icon>
			</view>
			<view class="text">
				格式要求：mp3、m4a、wav
			</view>
		</view> -->
		
		<!-- 底部按钮 -->
		<view class="footer_none"></view>
		<view v-if="!isOk" class="footer_yellow_btn disabled" >
			立即提交合成
		</view>
		<view v-if="(tabsIndex==0&&audioUrl)||(tabsIndex==1&&textarea&&textAudioUrl)" class="footer_yellow_btn" @click="showPromise = true,clickOnStopAudio()">
			立即提交合成
		</view>
		
		
		<!-- 承诺 -->
		<u-popup :show="showPromise" :closeable="true" mode="center" bgColor="#484848" round="10rpx" :safeAreaInsetBottom="false" @close="closePromise" @open="openPromise">
			<view class="promise">
				<view class="title">
					{{instructions.title}}
				</view>
				<view class="text">
					{{instructions.content}}
				</view>
				<view class="btn" @click="clickAgree">
					我已知晓，同意
				</view>
			</view>
		</u-popup>
		<u-toast ref="uToast"></u-toast>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				tabsIndex: 0,
				isSoundPlay: 0,
				play: false,
				isOk: false,
				textarea: '',
				showPromise: false,
				userId:'',
				id:'',
				title:'',
				videoUrl:'',
				voiceId:'',
				voiceType:'',
				speakerId:'',
				
				audioUrl:'',
				audioName:'',
				
				innerAudioContext:null,
				isAudioPaly:false,
				
				recorderManager: null, // 录音管理对象
				isRecording: false,    // 录音状态
				timer: null,           // 计时器
				recordingTime: 0,      // 录音时间（秒）
				timerDisplay: '00:00',// 显示的录音时长
				
				audioTitle:'',
				livesConfigInfo:{},
				intervalId: null,
				textAudioUrl: '',
				aliyunOssSign: {},
				isPrivate:'',
				videoImg:'',
				itemId:'',
				instructions:{},
			}
		},
		onLoad(opt) {
			const that = this
			this.userId = uni.getStorageSync('userId');
			try{
				if(uni.getStorageSync('userInfo')){
					
					if(this.userId == 0){
						this.userId = uni.getStorageSync('userInfo').user_id;
					}
				}
			}catch(error){
				console.error('json parse error', error);
			}
			this.id = opt.id
			console.log('-synth-onload--this.id--', this.id);
			this.isPrivate = opt.isPrivate
			this.title = opt.title
			this.itemId = opt.itemId
			this.getLivesConfigInfo()
			this.getAliyunOssSing()
			this.getReadTextExample()
			
			// 创建录音管理器
			this.recorderManager = uni.getRecorderManager();
			// 监听录音开始事件
			this.recorderManager.onStart(() => {
				console.log('录音开始');
				this.isRecording = true;
				this.startTimer();
			});
			// 监听录音停止事件
			this.recorderManager.onStop((res) => {
				console.log('录音停止，录音文件路径：', res.tempFilePath);
				if(res.duration < 3000){
					this.$refs.uToast.show({
						message: "录音时长限制：3秒 ～ 60秒"
					})
				}else{
					this.audioUrl = res.tempFilePath
					this.isSoundPlay = 2
					const timestamp = new Date().getTime();
					const randomNum = Math.floor(Math.random() * 10000);
					const fileName = timestamp + "_" + randomNum +  this.audioUrl.substring(this.audioUrl.lastIndexOf('.'));
					this.audioName = fileName
					console.log('音频名称---',fileName)
				}
				this.isRecording = false;
				this.stopTimer();
				// 停止后可以拿到录音文件路径 res.tempFilePath，进行后续处理
			});
			// 监听录音错误事件
			this.recorderManager.onError((err) => {
				console.log('录音出错：', err);
				this.isRecording = false;
				this.isSoundPlay = 0
				this.stopTimer();
			});
			
			
			// 播放声音管理器
			this.innerAudioContext = uni.createInnerAudioContext();
			this.innerAudioContext.onPlay(() => {
				console.log('开始播放');
				this.isAudioPaly = true
			});
			this.innerAudioContext.onStop(() => {
				console.log('停止播放');
				this.isAudioPaly = false
			});
			this.innerAudioContext.onEnded(() => {
				console.log('自然播放结束');
				this.isAudioPaly = false
			});
			
			
		},
		methods: {
			// 协议
			getReadTextExample(){
				uni.$u.http.get('/api/speed_txt_example/'+this.userId +'?from=miniprogram').then(res => {
					if(res.data && res.data.data){
						console.log('协议-----',res.data.data)
						this.instructions = res.data.data.instructions
					}
				}).catch(err => {
					console.log(err)
				})
			},
			// 合成作品列表
			getAssetsList(job_id){
				uni.$u.http.get('/api/speed_assets_list/'+this.userId +'?from=miniprogram&type=1&job_id='+job_id).then(res => {
					if(res.data && res.data.data){
						console.log('合成作品列表-----',res.data.data)
						if(res.data.data[0].status == 3){
							uni.hideLoading();
							clearInterval(this.intervalId);
							this.intervalId = null;
							this.textAudioUrl = res.data.data[0].url
							this.innerAudioContext.src = this.textAudioUrl;
							this.innerAudioContext.play();
						}
						else if(res.data.data[0].status == 4){
							uni.hideLoading();
							uni.showToast({
								title: '合成失败',
								duration: 2000,
								icon: 'none'
							});
						}
					}
				}).catch(err => {
					console.log(err)
				})
			},
			// 音频合成
			postSpeedAudioCreate(){
				if(!this.speakerId){
					if(!this.voiceId){
						uni.showToast({
							title: '请先设置角色声音',
							duration: 2000,
							icon:'none'
						});
						return
					}
				}
				
				uni.showLoading({
					title: '合成中',
					mask: true
				});
				const postData = {
					title: this.title,
					video_url: this.videoUrl,
					voice_id: this.voiceId,
					voice_type: this.voiceType,
					speaker_id: this.speakerId,
					text: this.textarea,
					only_generate_audio: 1
				}
				uni.$u.http.post('/api/speed_create/'+this.userId +'?from=miniprogram', postData).then(res => {
					if(res.data && res.data.data){
						console.log('音频合成-----',res.data.data)
						this.intervalId = setInterval(() => {
							this.getAssetsList(res.data.data.job_id)
						}, 1000);
					}
				}).catch(err => {
					console.log(err)
				})
			},
			// 视频合成
			postSpeedCreate(){
				uni.showLoading({
					title: '合成中',
					mask: true
				});
				const postData = {
					live_video_id: this.itemId,
					title: this.title,
					video_url: this.videoUrl,
				}
				if(this.tabsIndex == 0){
					postData.audio_url = this.audioUrl
				}
				else if(this.tabsIndex == 1){
					
					if(!this.textAudioUrl){
						uni.showToast({
							title: '请先合成声音',
							duration: 2000,
							icon:'none'
						});
						return
					}
					postData.audio_url = this.textAudioUrl
					postData.text = this.textarea
					postData.voice_id = this.voiceId
					postData.voice_type = this.voiceType
				}
				uni.$u.http.post('/api/speed_create/'+this.userId +'?from=miniprogram', postData).then(res => {
					console.log('作品合成-----',res.data)
					uni.hideLoading();
					if(res.data.status == 0){
						uni.showToast({
							title: '合成失败，没有足够氪气值',
							duration: 3000,
							icon:'none'
						});
						return 
					}

					console.log('---synth-this.id--', this.id);
					console.log('---synth-this.isPrivate--', this.isPrivate);
					uni.redirectTo({
						url: '/scenePages/sceneSet/sceneSet?id='+this.id+'&isPrivate='+this.isPrivate
					});
					
					/* // 返回上一页面，并触发上一页面的onShow方法
					uni.navigateBack({
						delta: 1
					}); */
					
				}).catch(err => {
					console.log(err)
				})
			},
			// 获取互动扩展信息
			getLivesConfigInfo(){
				uni.$u.http.get('/api/aigc_lives_config/'+this.userId +'?from=miniprogram&live_id='+this.id).then(res => {
					if(res.data && res.data.data){
						console.log('获取互动扩展信息-----',res.data.data)
						this.livesConfigInfo = res.data.data
						this.videoUrl = this.livesConfigInfo.detail.default_video.url
						this.videoImg = this.livesConfigInfo.detail.default_video.image_file
						this.voiceId = this.livesConfigInfo.detail.default_audio.voice_id
						this.speakerId = this.livesConfigInfo.detail.default_audio.speaker_id
						this.voiceType = this.livesConfigInfo.detail.default_audio.type
						this.audioTitle = this.livesConfigInfo.detail.default_audio.title
					}
				}).catch(err => {
					console.log(err)
				})
			},
			// 开始录音
			recorderStart(){
				this.recorderManager.start({sampleRate:44100,encodeBitRate:320000})
			},
			// 结束录音
			recorderEnd(){
				this.recorderManager.stop()
			},
			// 播放试听
			clickOnPlayAudio(){
				this.innerAudioContext.src = this.audioUrl;
				this.innerAudioContext.play();
			},
			// 停止试听
			clickOnStopAudio(){
				this.innerAudioContext.stop();
			},
			// 重新上传
			reUpload(){
				this.innerAudioContext.stop();
				this.isAudioPaly = false
				this.isSoundPlay = 0
			},
			//从微信聊天上传文件
			getWeixinFile() {
				const that = this
				wx.chooseMessageFile({
					count: 1,
					type: 'file', //video， image， file
					extension:['mp3', 'wav', 'm4a'],
					success(res) {
						console.log(res.tempFiles[0])
						//const tempFilePath = res.tempFiles[0].path;
						//const fileName = tempFilePath.substring(tempFilePath.lastIndexOf('/') + 1);
						if(res.tempFiles[0].size > (10*1024*1024)){
							that.$refs.uToast.show({
								message: "音频不能大于10MB"
							})
							return
						}
						that.audioUrl = res.tempFiles[0].path;
						//that.audioName = that.audioUrl.substring(that.audioUrl.lastIndexOf('/') + 1);
						const timestamp = new Date().getTime();
						const randomNum = Math.floor(Math.random() * 10000);
						const fileName = timestamp + "_" + randomNum + that.audioUrl.substring(that.audioUrl.lastIndexOf('.'));
						that.audioName = fileName
						
						that.isSoundPlay = 2
					}
				})
			},
			// 获取阿里云上传请求参数
			getAliyunOssSing(){
				uni.$u.http.get('/api/aliyun_oss_sign/'+this.userId +'?from=miniprogram').then(res => {
					if(res.data && res.data.data){
						console.log('阿里云请求参数-----',res.data.data)
						this.aliyunOssSign = res.data.data;
					}
				}).catch(err => {
					console.log(err)
				})
			},
			// 上传文件到阿里云
			uploadFileAliyun(){
				const that = this
				uni.showLoading({
					title: '上传中',
					mask: true
				});
				uni.uploadFile({
					url: that.aliyunOssSign.host,
					filePath: that.audioUrl,
					name: 'file',
					formData: {
						key: that.aliyunOssSign.dir + that.audioName,
						policy: that.aliyunOssSign.policy,
						OSSAccessKeyId: that.aliyunOssSign.accessid,
						signature: that.aliyunOssSign.signature
					},
					success: (resa) => {
						console.log('上传------',resa)
						if(resa.statusCode == 204)
						{
							that.audioUrl = that.aliyunOssSign.host +'/'+ that.aliyunOssSign.dir + that.audioName
							uni.hideLoading();
							that.postSpeedCreate()
						}
						else{
							uni.hideLoading();
							that.$refs.uToast.show({
								message: "上传失败,请重新上传"
							})
						}
					}
				});
			},
			clickAgree(){
				this.showPromise = false
				if(this.tabsIndex == 0){
					this.uploadFileAliyun()
				}
				else if(this.tabsIndex == 1){
					this.postSpeedCreate()
				}
				
			},
			openPromise() {
				// console.log('open');
			},
			closePromise() {
				this.showPromise = false
				// console.log('close');
			},
			clickTabs(index){
				this.tabsIndex = index
			},
			// 启动计时器
			startTimer() {
				this.recordingTime = 0;
				this.timer = setInterval(() => {
					this.recordingTime++;
					this.updateTimerDisplay();
				}, 1000); // 每隔 1 秒更新一次
			},
			// 停止计时器
			stopTimer() {
				clearInterval(this.timer);
				this.timerDisplay = '00:00'; // 重置计时器显示
			},
			// 更新计时器显示（格式：MM:SS）
			updateTimerDisplay() {
				let minutes = Math.floor(this.recordingTime / 60);
				let seconds = this.recordingTime % 60;
				this.timerDisplay = this.formatTime(minutes) + ':' + this.formatTime(seconds);
			},
			// 格式化时间为两位数
			formatTime(value) {
				return value < 10 ? '0' + value : value;
			}
		}
	}
</script>

<style lang="scss" scoped>
.promise{
	width: 560rpx;
	box-sizing: border-box;
	padding:0 30rpx 35rpx;
	.btn{
		height: 70rpx;
		border-radius: 35rpx;
		background: #F9BE01;
		line-height: 70rpx;
		text-align: center;
		color: #3D3D3D;
		font-size: 26rpx;
		font-weight: 600;
		margin-top: 25rpx;
	}
	.title{
		text-align: center;
		font-size: 26rpx;
		font-weight: normal;
		line-height: 40rpx;
		color: #FFFFFF;
		padding:25rpx 0 25rpx;
	}
	.text{
		font-size: 20rpx;
		font-weight: normal;
		line-height: 32rpx;
		color: #FFFFFF;
		text-align: justify;
	}
}
.textarea_sound{
	position: relative;
	height: 210rpx;
	border-radius: 8rpx;
	background: #4B4B4B;
	margin: 40rpx 40rpx 0;
	.textarea_btn{
		position: absolute;
		right: 15rpx;
		bottom: 15rpx;
		z-index: 9;
		width: 106rpx;
		height: 48rpx;
		border-radius: 30rpx;
		background: #F9BE01;
		font-size: 22rpx;
		font-weight: normal;
		line-height: 48rpx;
		text-align: center;
		color: #000000;
		text-align: center;
		&.disabled{
			opacity: 0.3;
		}
	}
	.textarea{
		border:none;
		background: none;
		font-size: 26rpx;
		font-weight: normal;
		line-height: 40rpx;
		color: #fff;
		box-sizing: border-box;
		padding:14rpx 20rpx;
	}
}
.text_sound{
	padding:40rpx;
	.title{
		font-size: 25rpx;
		line-height: 40rpx;
		color: #9F9F9F;
	}
	.text{
		padding-top: 20rpx;
		font-size: 26rpx;
		font-weight: 600;
		line-height: 40rpx;
		color: #FFFFFF;
	}
}
.step3_btn{
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding:100rpx 120rpx;
	.item{
		width: 130rpx;
		.btn_reload{
			width: 130rpx;
			height: 130rpx;
			border-radius: 50%;
			background: #494949;
			display: flex;
			align-items: center;
			justify-content: center;
			.bgff{
				background: #fff;
				width: 46rpx;
				height: 46rpx;
				border-radius: 10rpx;
				display: flex;
				align-items: center;
				justify-content: center;
			}
		}
		.btn_listen{
			width: 130rpx;
			height: 130rpx;
			border-radius: 50%;
			background: #F9BE01;
			display: flex;
			align-items: center;
			justify-content: center;
		}
		.name{
			text-align: center;
			font-size: 26rpx;
			font-weight: normal;
			line-height: 40rpx;
			color: #FFFFFF;
			padding-top: 40rpx;
		}
	}
}
.read_end{
	text-align: center;
	padding:40rpx 0;
	.name{
		font-size: 34rpx;
		font-weight: normal;
		line-height: 50rpx;
		color: #FFFFFF;
		text-shadow: 0px 2px 4px rgba(0, 0, 0, 0.2613);
	}
	.text{
		padding:10rpx 0 30rpx;
		font-size: 26rpx;
		font-weight: normal;
		line-height: 40rpx;
		color: #9B9B9B;
	}
	.ico{
		display: block;
		width: 152rpx;
		height: 135rpx;
		margin: 0 auto;
	}
	.time{
		font-size: 26rpx;
		font-weight: normal;
		line-height: 40rpx;
		color: #fff;
		text-align: center;
		padding:30rpx 0 40rpx;
	}
	.btn{
		width: 590rpx;
		height: 70rpx;
		border-radius: 37rpx;
		background: #494949;
		font-size: 26rpx;
		font-weight: 500;
		line-height: 70rpx;
		color: #fff;
		margin: 0 auto;
	}
}
.read_play{
	display: flex;
	align-items: center;
	justify-content: center;
	flex-direction: column;
	padding: 50rpx 0 60rpx;
	.btn{
		width: 216rpx;
		height: 216rpx;
		background: rgba(249, 190, 1, 0.1519);
		border-radius: 50%;
		box-sizing: border-box;
		border: 2rpx solid #F9BE01;
		display: flex;
		align-items: center;
		justify-content: center;
	}
	.name{
		padding-top: 40rpx;
		font-size: 26rpx;
		font-weight: normal;
		line-height: 40rpx;
		color: #FFFFFF;
	}
}
.synth_drive{
	margin: 40rpx 40rpx 0;
	background: #393939;
	border-radius: 15rpx;
	.tabs_nav{
		display: flex;
		align-items: center;
		justify-content: center;
		.item{
			font-size: 26rpx;
			font-weight: normal;
			line-height: 40rpx;
			text-align: center;
			color: #9B9B9B;
			padding:40rpx 30rpx 15rpx;
			position: relative;
			&.hover{
				font-size: 26rpx;
				font-weight: 600;
				line-height: 40rpx;
				text-align: center;
				color: #FFFFFF;
				&::after{
					content: '';
					position: absolute;
					left:50%;
					bottom: 0;
					width: 48rpx;
					height: 6rpx;
					border-radius: 3rpx;
					background: #FFB200;
					margin-left: -24rpx;
					
				}
			}
		}
	}
}
.synth_video{
	margin: 10rpx 40rpx 0;
	height: 430rpx;
	background: #393939;
	text-align: center;
	border-radius: 15rpx;
	.ph{
		height: 430rpx;
	}
}
.wx_up{
	margin: 40rpx 40rpx 0;
	height: 270rpx;
	border-radius: 15rpx;
	background: #393939;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-direction: column;
	.text{
		font-size: 20rpx;
		font-weight: normal;
		line-height: 30rpx;
		color: #A6A6A6;
		padding-top: 18rpx;
	}
	.name{
		display: flex;
		align-items: center;
		justify-content: center;
		&.yellow{
			color: #F9BE01;
		}
		&.green{
			color: #00E16F;
		}
		text{
			display: block;
			font-size: 26rpx;
			font-weight: 500;
			line-height: 40rpx;
			padding-right: 6rpx;
		}
	}
}
.footer_none{
	width: 100%;
	height: 160rpx;
}
.footer_yellow_btn{
	position: fixed;
	left:40rpx;
	right: 0;
	bottom: 60rpx;
	width: 670rpx;
	height: 70rpx;
	border-radius: 35rpx;
	background: #F9BE01;
	line-height: 70rpx;
	text-align: center;
	font-size: 26rpx;
	color: #292D32;
	font-weight: 600;
	z-index: 999;
	&.disabled{
		opacity: 0.3;
	}
}
</style>
